package com.och.mrcp.handler;

import com.och.mrcp.config.EngineConfig;
import com.och.mrcp.core.mrcp.factory.MrcpMessageFactory;
import com.och.mrcp.core.mrcp.model.MrcpEvent;
import com.och.mrcp.core.mrcp.model.MrcpMessage;
import com.och.mrcp.core.mrcp.model.MrcpRequest;
import com.och.mrcp.core.mrcp.model.MrcpResponse;
import com.och.mrcp.core.mrcp.parser.MrcpMessageParser;
import com.och.mrcp.model.RecognitionResult;
import com.och.mrcp.service.MediaSessionManager;
import com.och.mrcp.service.MediaSessionManager.MediaSession;
import com.och.mrcp.service.SipMrcpSynthesisService;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandler.Sharable;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Component;

import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.concurrent.*;

/**
 * MRCPv2消息处理器
 * 处理接收到的MRCP消息，与MediaSessionManager集成
 * RFC 6787 - Media Resource Control Protocol Version 2 (MRCPv2)
 */
@Slf4j
@Component
@Sharable
public class MrcpMessageHandler extends SimpleChannelInboundHandler<ByteBuf> {

    @Lazy
    @Autowired
    private MediaSessionManager mediaSessionManager;
    


    @Lazy
    @Autowired
    private VoiceRecognitionSessionHandler voiceRecognitionSessionHandler;
    
    @Lazy
    @Autowired
    private SipMrcpSynthesisService sipMrcpSynthesisService;
    
    @Autowired
    private EngineConfig engineConfig;
    
    // MRCP通道到Call-ID的映射
    private final Map<ChannelHandlerContext, String> channelCallIdMap = new ConcurrentHashMap<>();
    
    // 语法存储：Call-ID -> Grammar Content
    private final Map<String, String> grammarStorage = new ConcurrentHashMap<>();
    
    @Override
    protected void channelRead0(ChannelHandlerContext ctx, ByteBuf msg) {
        try {
            // 读取消息内容
            byte[] bytes = new byte[msg.readableBytes()];
            msg.readBytes(bytes);
            String messageStr = new String(bytes, StandardCharsets.UTF_8);
            
            InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
            log.info("Received MRCP message from {}:{}, size: {} bytes", 
                    remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort(), bytes.length);
            log.debug("MRCP message content: {}", messageStr);
            
            // 添加十六进制调试信息
            if (log.isDebugEnabled()) {
                StringBuilder hexDump = new StringBuilder();
                for (int i = 0; i < Math.min(bytes.length, 100); i++) { // 只显示前100字节
                    hexDump.append(String.format("%02X ", bytes[i] & 0xFF));
                    if ((i + 1) % 16 == 0) {
                        hexDump.append("\n");
                    }
                }
                log.debug("MRCP message hex dump (first 100 bytes):\n{}", hexDump.toString());
            }
            
            // 检查消息是否为空或只包含空白字符
            if (messageStr.trim().isEmpty()) {
                log.warn("Received empty MRCP message from {}:{}", 
                        remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort());
                return;
            }
            
            // 解析MRCP消息
            MrcpMessage mrcpMessage = MrcpMessageParser.parse(messageStr);
            
            // 处理消息
            handleMrcpMessage(mrcpMessage, ctx);
            
        } catch (Exception e) {
            log.error("Error processing MRCP message: {}", e.getMessage(), e);
            // 发送错误响应
            sendErrorResponse(ctx, e);
        }
    }
    
    /**
     * 处理MRCP消息
     */
    private void handleMrcpMessage(MrcpMessage message, ChannelHandlerContext ctx) {
        try {
            if (message == null) {
                log.warn("Received null MRCP message");
                return;
            }
            
            // 提取Call-ID（从Session-Id头部或Channel-Identifier）
            String callId = extractCallId(message);
            if (callId != null) {
                channelCallIdMap.put(ctx, callId);
                log.info("Mapped MRCP channel to Call-ID: {}", callId);
                
                // 获取真正的SIP Call-ID
                String actualCallId = getSipCallId(message, callId);
                if (actualCallId != null) {
                    // 注册MRCP消息回调，将此通道与SIP Call-ID关联
                    registerMrcpCallback(actualCallId, ctx);
                    log.debug("Registered MRCP callback with SIP Call-ID: {}", actualCallId);
                } else {
                    log.warn("Could not find SIP Call-ID for MRCP channel Call-ID: {}", callId);
                }
            } else {
                log.warn("Could not extract Call-ID from MRCP message");
            }
            
            log.info("Processing MRCP message: type={}, resource={}, callId={}", 
                    message.getMessageType(), 
                    message.getResourceType(), 
                    callId);
            
            // 记录当前会话状态用于调试
            mediaSessionManager.logActiveSessions();

            switch (message.getMessageType()) {
                case REQUEST:
                    handleRequest(message, ctx, callId);
                    break;
                case RESPONSE:
                    handleResponse(message, ctx, callId);
                    break;
                case EVENT:
                    handleEvent(message, ctx, callId);
                    break;
                default:
                    log.warn("Unknown message type: {}", message.getMessageType());
            }
        } catch (Exception e) {
            log.error("Error handling MRCP message: {}", e.getMessage(), e);
            // 发送错误响应
            sendErrorResponse(ctx, e);
        }
    }
    
    /**
     * 从MRCP消息中提取Call-ID
     */
    private String extractCallId(MrcpMessage message) {
        if (message == null) {
            log.warn("Message is null, cannot extract Call-ID");
            return null;
        }
        
        // 1. 尝试从Channel-Identifier头部提取
        String channelIdentifier = message.getHeader("Channel-Identifier");
        if (channelIdentifier != null && !channelIdentifier.trim().isEmpty()) {
            // Channel-Identifier格式: channelId@resourceType
            if (channelIdentifier.contains("@")) {
                String callId = channelIdentifier.split("@")[0];
                log.debug("Extracted Call-ID from Channel-Identifier: {} -> {}", channelIdentifier, callId);
                return callId;
            } else {
                log.debug("Channel-Identifier does not contain @: {}", channelIdentifier);
            }
        }
        
        // 2. 尝试从Session-Id头部提取
        String sessionId = message.getHeader("Session-Id");
        if (sessionId != null && !sessionId.trim().isEmpty()) {
            log.debug("Extracted Call-ID from Session-Id: {}", sessionId);
            return sessionId;
        }
        
        // 3. 尝试从通用Call-ID头部提取
        String callIdHeader = message.getHeader("Call-ID");
        if (callIdHeader != null && !callIdHeader.trim().isEmpty()) {
            log.debug("Extracted Call-ID from Call-ID header: {}", callIdHeader);
            return callIdHeader;
        }
        
        // 4. 如果都没有找到，记录详细信息用于调试
        log.warn("Could not extract Call-ID from MRCP message. Available headers: {}", 
                message.getAllHeaders().keySet());
        return null;
    }
    
    /**
     * 处理MRCP请求消息
     */
    private void handleRequest(MrcpMessage message, ChannelHandlerContext ctx, String callId) {
        if (message == null) {
            log.warn("Received null MRCP request message");
            return;
        }
        
        // 尝试通过Channel-Identifier查找正确的Call-ID
        String channelIdentifier = message.getHeader("Channel-Identifier");
        String actualCallId = callId;
        
        if (channelIdentifier != null && !channelIdentifier.trim().isEmpty()) {
            // 通过MediaSessionManager查找对应的SIP Call-ID
            String mappedCallId = mediaSessionManager.findCallIdByMrcpChannel(channelIdentifier);
            if (mappedCallId != null) {
                actualCallId = mappedCallId;
                log.info("Mapped MRCP channel {} to SIP Call-ID: {}", channelIdentifier, actualCallId);
            } else {
                log.warn("No SIP Call-ID mapping found for MRCP channel: {}", channelIdentifier);
            }
        }
        
        // 检查媒体会话是否存在
        MediaSession mediaSession = mediaSessionManager.getMediaSession(actualCallId);
        if (mediaSession == null) {
            log.warn("No media session found for Call-ID: {}, creating one", actualCallId);
            // 这里可以创建一个新的媒体会话，或者发送错误响应
            sendMethodFailureResponse(ctx, message, "No media session found");
            return;
        }
        
        log.info("Handling MRCP request for Call-ID: {}, Resource: {}, Method: {}", 
                actualCallId, message.getResourceType(), message.getMessageTypeDescription());
        
        // 根据资源类型处理请求
        switch (message.getResourceType()) {
            case SPEECHRECOG:
                if (message instanceof MrcpRequest) {
                    MrcpRequest request = (MrcpRequest) message;
                    switch (request.getMethod()) {
                        case DEFINE_GRAMMAR:
                            handleDefineGrammarRequest(request, ctx, actualCallId);
                            break;
                        case RECOGNIZE:
                        case RECOGNIZE_ONESHOT:
                            handleSpeechRecognitionRequest(request, ctx, actualCallId);
                            break;
                        case STOP:
                            handleStopRecognitionRequest(request, ctx, actualCallId);
                            break;
                        default:
                            log.info("Unhandled speech recognition method: {}", request.getMethod());
                            sendMethodFailureResponse(ctx, request, "Method not implemented");
                            break;
                    }
                }
                break;
            case SPEECHSYNTH:
                handleSpeechSynthesisRequest(message, ctx, actualCallId);
                break;
            default:
                log.warn("Unsupported resource type: {}", message.getResourceType());
                sendMethodFailureResponse(ctx, message, "Unsupported resource type");
                break;
        }
    }
    
    /**
     * 处理语音识别请求
     */
    private void handleSpeechRecognitionRequest(MrcpMessage request, ChannelHandlerContext ctx, String callId) {
        log.info("Processing speech recognition request for Call-ID: {}", callId);
        
        try {
            // 1. 获取媒体会话信息
            MediaSessionManager.MediaSession mediaSession =
                mediaSessionManager.getMediaSession(callId);
            if (mediaSession == null) {
                log.error("No media session found for Call-ID: {}", callId);
                sendMethodFailureResponse(ctx, request, "Media session not found");
                return;
            }
            
            // 2. 创建识别配置
            EngineConfig.RecognitionConfig config = engineConfig.createRecognitionConfig(engineConfig.getDefaultProvider());
            
            // 从MRCP请求中覆盖配置（如果有提供）
            String language = request.getHeaders().get("Content-Language");
            if (language != null) {
                config.setLanguage(language);
            }
            
            String punctuation = request.getHeaders().get("Enable-Punctuation");
            if (punctuation != null) {
                config.setEnablePunctuation(Boolean.parseBoolean(punctuation));
            }
            

            
            // 4. 立即发送IN-PROGRESS响应，符合MRCP规范，提示对端可开始发送RTP
            sendProgressResponse(ctx, request, 200, "IN-PROGRESS");

            // 5. 异步启动语音识别会话（使用新的会话管理）
            CompletableFuture<RecognitionResult> recognitionFuture = 
                voiceRecognitionSessionHandler.handleRecognizeRequest(callId, config, (MrcpRequest) request);

            // 可选：仅用于日志，记录引擎就绪时间点
            voiceRecognitionSessionHandler.waitForEngineReady(callId)
                .thenRun(() -> log.info("Engine ready for Call-ID: {}", callId))
                .exceptionally(throwable -> { 
                    log.warn("Engine startup failed for Call-ID: {}: {}", callId, throwable.getMessage()); 
                    return null; 
                });
            
            // 6. 处理识别结果
            recognitionFuture.thenAccept(result -> {
                try {
                    log.info("Recognition completed for Call-ID: {}, result: {}", 
                            callId, result.getText());
                    
                    // 生成NLSML格式的识别结果
                    String nlsmlResult = generateNlsmlResult(result, callId);
                    
                    // 发送RECOGNITION-COMPLETE事件
                    sendMrcpEvent(ctx, request, "RECOGNITION-COMPLETE", nlsmlResult);
                    
                    // 发送最终响应
                    sendFinalResponse(ctx, request, 200, "OK");
                    
                } catch (Exception e) {
                    log.error("Error handling recognition result for Call-ID: {}", callId, e);
                    sendMethodFailureResponse(ctx, request, "Error handling recognition result");
                }
            }).exceptionally(throwable -> {
                log.error("Recognition failed for Call-ID: {}", callId, throwable);
                // 发送错误响应
                sendFinalErrorResponse(ctx, request, "Recognition failed: " + throwable.getMessage());
                return null;
            });
            
        } catch (Exception e) {
            log.error("Error starting recognition session for Call-ID: {}", callId, e);
            // 如果在引擎启动过程中发生错误，发送失败响应
            sendMethodFailureResponse(ctx, request, "Failed to start recognition: " + e.getMessage());
        }
    }
    
    /**
     * 处理语音识别停止请求
     */
    private void handleStopRecognitionRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId) {
        log.info("Processing STOP recognition request for Call-ID: {}", callId);
        
        try {
            // 1. 停止语音识别会话
            CompletableFuture<Void> stopFuture = voiceRecognitionSessionHandler.handleStopRequest(callId);
            
            // 2. 处理停止结果
            stopFuture.thenAccept(result -> {
                try {
                    log.info("Recognition stopped successfully for Call-ID: {}", callId);
                    
                    // 发送STOP响应
                    sendFinalResponse(ctx, request, 200, "OK");
                    
                } catch (Exception e) {
                    log.error("Error handling stop result for Call-ID: {}", callId, e);
                    sendMethodFailureResponse(ctx, request, "Error handling stop result");
                }
            }).exceptionally(throwable -> {
                log.error("Stop recognition failed for Call-ID: {}", callId, throwable);
                sendMethodFailureResponse(ctx, request, "Stop failed: " + throwable.getMessage());
                return null;
            });
            
        } catch (Exception e) {
            log.error("Error stopping recognition session for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to stop recognition: " + e.getMessage());
        }
    }
    
    /**
     * 处理语音合成请求
     */
    private void handleSpeechSynthesisRequest(MrcpMessage message, ChannelHandlerContext ctx, String callId) {
        log.info("Processing speech synthesis request for Call-ID: {}", callId);
        
        if (!(message instanceof MrcpRequest)) {
            log.warn("Message is not a MRCP request: {}", message.getClass().getSimpleName());
            sendMethodFailureResponse(ctx, message, "Invalid message type");
            return;
        }
        
        MrcpRequest request = (MrcpRequest) message;
        
        try {
            // 1. 获取媒体会话信息
            com.och.mrcp.service.MediaSessionManager.MediaSession mediaSession = 
                mediaSessionManager.getMediaSession(callId);
            if (mediaSession == null) {
                log.error("No media session found for Call-ID: {}", callId);
                sendMethodFailureResponse(ctx, request, "Media session not found");
                return;
            }
            
            // 2. 根据MRCP方法类型处理请求
            switch (request.getMethod()) {
                case SPEAK:
                    handleSpeakRequest(request, ctx, callId, mediaSession);
                    break;
                case STOP:
                    handleStopSynthesisRequest(request, ctx, callId);
                    break;
                case PAUSE:
                    handlePauseSynthesisRequest(request, ctx, callId);
                    break;
                case RESUME:
                    handleResumeSynthesisRequest(request, ctx, callId);
                    break;
                default:
                    log.warn("Unsupported synthesis method: {}", request.getMethod());
                    sendMethodFailureResponse(ctx, request, "Unsupported method: " + request.getMethod());
                    break;
            }
            
        } catch (Exception e) {
            log.error("Error processing synthesis request for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to process request: " + e.getMessage());
        }
    }
    
    /**
     * 处理SPEAK请求
     */
    private void handleSpeakRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId, 
                                   com.och.mrcp.service.MediaSessionManager.MediaSession mediaSession) {
        try {
            // 1. 从请求中提取要合成的文本
            String textToSynthesize = extractTextFromRequest(request);
            if (textToSynthesize == null || textToSynthesize.trim().isEmpty()) {
                log.error("No text to synthesize in request for Call-ID: {}", callId);
                sendMethodFailureResponse(ctx, request, "No text to synthesize");
                return;
            }
            
            // 2. 创建RTP地址
            InetSocketAddress rtpAddress = new InetSocketAddress(
                mediaSession.getClientAddress().getAddress(), 
                mediaSession.getRtpPort()
            );
            
            // 3. 按MRCP规范：在发送RTP前先回复 200 IN-PROGRESS
            sendProgressResponse(ctx, request, 200, "IN-PROGRESS");

            // 4. 使用SipMrcpSynthesisService处理SPEAK请求（随后开始RTP推送）
            CompletableFuture<Void> synthesisFuture = sipMrcpSynthesisService.handleSpeakRequest(
                callId, request, rtpAddress
            );
            
            // 5. 处理合成结果（异步）
            synthesisFuture.exceptionally(throwable -> {
                log.error("SPEAK request failed for Call-ID: {}", callId, throwable);
                // 注意：这里不再发送响应，因为已经发送了立即响应
                // 错误会通过SPEAK-FAILED事件发送
                return null;
            });
            
        } catch (Exception e) {
            log.error("Error handling SPEAK request for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to start SPEAK: " + e.getMessage());
        }
    }
    
    /**
     * 处理STOP语音合成请求
     */
    private void handleStopSynthesisRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId) {
        try {
            sipMrcpSynthesisService.handleStopRequest(callId, request);
            sendMethodSuccessResponse(ctx, request, "STOP completed");
        } catch (Exception e) {
            log.error("Error handling STOP request for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to stop synthesis: " + e.getMessage());
        }
    }
    
    /**
     * 处理PAUSE语音合成请求
     */
    private void handlePauseSynthesisRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId) {
        try {
            sipMrcpSynthesisService.handlePauseRequest(callId, request);
            sendMethodSuccessResponse(ctx, request, "PAUSE completed");
        } catch (Exception e) {
            log.error("Error handling PAUSE request for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to pause synthesis: " + e.getMessage());
        }
    }
    
    /**
     * 处理RESUME语音合成请求
     */
    private void handleResumeSynthesisRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId) {
        try {
            sipMrcpSynthesisService.handleResumeRequest(callId, request);
            sendMethodSuccessResponse(ctx, request, "RESUME completed");
        } catch (Exception e) {
            log.error("Error handling RESUME request for Call-ID: {}", callId, e);
            sendMethodFailureResponse(ctx, request, "Failed to resume synthesis: " + e.getMessage());
        }
    }
    

    
    /**
     * 从MRCP请求中提取要合成的文本
     */
    private String extractTextFromRequest(MrcpMessage request) {
        try {
            // 尝试从请求体中获取文本
            String body = request.getBody();
            if (body != null && !body.trim().isEmpty()) {
                return body.trim();
            }
            
            // 尝试从特定头部获取文本
            String text = request.getHeader("Content");
            if (text != null && !text.trim().isEmpty()) {
                return text.trim();
            }
            
            // 尝试从其他可能的头部获取
            text = request.getHeader("Text");
            if (text != null && !text.trim().isEmpty()) {
                return text.trim();
            }
            
            log.warn("No text found in MRCP request body or headers");
            return null;
            
        } catch (Exception e) {
            log.error("Error extracting text from MRCP request", e);
            return null;
        }
    }
    
    /**
     * 处理响应消息
     */
    private void handleResponse(MrcpMessage response, ChannelHandlerContext ctx, String callId) {
        log.info("Handling MRCP response for Call-ID: {}, Status: {}", 
                callId, response.getStatusCode());
        
        // 处理响应消息
        // 这里可能需要更新请求状态或触发后续操作
        if (response.getStatusCode() >= 400) {
            log.warn("MRCP error response received: {} - {}", 
                    response.getStatusCode(), response.getCompletionCause());
        }
    }
    
    /**
     * 处理事件消息
     */
    private void handleEvent(MrcpMessage event, ChannelHandlerContext ctx, String callId) {
        log.info("Handling MRCP event for Call-ID: {}, Event: {}", 
                callId, event.getMessageTypeDescription());
        
        // 通知MediaSessionManager处理MRCP事件
        String mrcpEventStr = event.encode();
        mediaSessionManager.handleMrcpEvent(callId, mrcpEventStr);
        
        // 处理事件消息
        // 这里可能需要通知上层应用或更新状态
    }
    
    /**
     * 处理DEFINE-GRAMMAR请求
     * 解析XML语法定义并存储，为后续的语音识别做准备
     */
    private void handleDefineGrammarRequest(MrcpRequest request, ChannelHandlerContext ctx, String callId) {
        try {
            log.info("Processing DEFINE-GRAMMAR request for Call-ID: {}", callId);
            MrcpResponse response = MrcpMessageFactory.createSuccessResponse(request);
            // 1. 解析语法定义内容
            String grammarContent = request.getBody();
            if (grammarContent == null || grammarContent.trim().isEmpty()) {
                log.warn("DEFINE-GRAMMAR request has no body content");
                sendMrcpMessage(ctx, response);
                return;
            }
            
            // 2. 验证语法内容（简单的XML格式检查）
            if (!grammarContent.contains("<grammar") || !grammarContent.contains("</grammar>")) {
                log.warn("Invalid grammar format in DEFINE-GRAMMAR request");
                sendMrcpMessage(ctx, response);
                return;
            }

            // 3. 存储语法定义到内存存储
            grammarStorage.put(callId, grammarContent);
            log.info("Grammar definition stored for Call-ID: {}, Content length: {} bytes",
                    callId, grammarContent.length());
            log.debug("Grammar content: {}", grammarContent);
            
            // 4. 发送成功响应
            sendMrcpMessage(ctx, response);

            log.info("DEFINE-GRAMMAR request processed successfully for Call-ID: {}", callId);
            
        } catch (Exception e) {
            log.error("Error processing DEFINE-GRAMMAR request for Call-ID {}: {}", callId, e.getMessage(), e);
            sendMethodFailureResponse(ctx, request, "Internal error processing grammar");
        }
    }
    

    
    /**
     * 发送最终响应
     */
    private void sendFinalResponse(ChannelHandlerContext ctx, MrcpMessage request, int statusCode, String reason) {
        try {
            if (request instanceof MrcpRequest) {
                MrcpRequest mrcpRequest = (MrcpRequest) request;
                
                // 构建最终响应
                MrcpResponse response;
                if (statusCode == 200) {
                    response = MrcpMessageFactory.createSuccessResponse(mrcpRequest);
                } else {
                    response = MrcpMessageFactory.createFailureResponse(mrcpRequest, statusCode, reason);
                }
                
                // 发送响应
                sendMrcpMessage(ctx, response);
            } else {
                log.warn("Cannot create response for non-request message");
            }
        } catch (Exception e) {
            log.error("Error sending final response: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送方法成功响应
     */
    private void sendMethodSuccessResponse(ChannelHandlerContext ctx, MrcpRequest request, String reason) {
        try {
            MrcpResponse response = MrcpMessageFactory.createSuccessResponse(request);
            response.getHeaders().put("Completion-Cause", "000");
            if (reason != null) {
                response.getHeaders().put("Completion-Reason", reason);
            }
            sendMrcpMessage(ctx, response);
            log.debug("Sent method success response for request: {}", request.getMethod());
        } catch (Exception e) {
            log.error("Error sending method success response: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送MRCP事件
     */
    private void sendMrcpEvent(ChannelHandlerContext ctx, MrcpMessage request, String eventType, String description) {
        try {
            if (request instanceof MrcpRequest) {
                MrcpRequest mrcpRequest = (MrcpRequest) request;
                
                // 根据事件类型创建相应的事件
                MrcpEvent event;
                switch (eventType.toUpperCase()) {
                    case "START-OF-INPUT":
                        event = MrcpMessageFactory.createStartOfInputEvent(mrcpRequest);
                        break;
                    case "RECOGNITION-COMPLETE":
                        event = MrcpMessageFactory.createRecognitionCompleteEvent(mrcpRequest, description);
                        break;
                    case "SPEAK-START":
                        event = MrcpMessageFactory.createSpeakStartEvent(mrcpRequest);
                        break;
                    case "SPEAK-COMPLETE":
                        event = MrcpMessageFactory.createSpeakCompleteEvent(mrcpRequest);
                        break;
                    default:
                        event = MrcpMessageFactory.createGenericEvent(mrcpRequest, eventType, "IN-PROGRESS");
                        break;
                }
                
                // 发送事件
                sendMrcpMessage(ctx, event);
            } else {
                log.warn("Cannot create event for non-request message");
            }
        } catch (Exception e) {
            log.error("Error sending MRCP event: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送方法失败响应
     */
    private void sendMethodFailureResponse(ChannelHandlerContext ctx, MrcpMessage request, String reason) {
        try {
            if (request instanceof MrcpRequest) {
                log.debug("Creating method failure response for reason: {}", reason);
                
                // 构建失败响应
                MrcpResponse response = MrcpMessageFactory.createMethodFailureResponse((MrcpRequest) request, reason);
                
                log.debug("Created failure response with completion cause: {}", response.getHeader("Completion-Cause"));
                
                // 发送响应
                sendMrcpMessage(ctx, response);
            } else {
                log.warn("Cannot create failure response for non-request message");
            }
        } catch (Exception e) {
            log.error("Error sending method failure response: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送RECOGNITION-COMPLETE事件（当已经发送了IN-PROGRESS后发生错误）
     * 参考Cairo项目的正确模式：发送事件而不是响应
     */
    private void sendFinalErrorResponse(ChannelHandlerContext ctx, MrcpMessage request, String reason) {
        try {
            if (request instanceof MrcpRequest) {
                log.debug("Creating RECOGNITION-COMPLETE event for error reason: {}", reason);
                
                // 参考Cairo项目：发送RECOGNITION-COMPLETE事件，状态为COMPLETE
                MrcpEvent event = MrcpMessageFactory.createRecognitionCompleteErrorEvent((MrcpRequest) request, reason);
                
                log.debug("Created RECOGNITION-COMPLETE event with completion cause: {}", event.getHeader("Completion-Cause"));
                
                // 发送事件
                sendMrcpMessage(ctx, event);
            } else {
                log.warn("Cannot create RECOGNITION-COMPLETE event for non-request message");
            }
        } catch (Exception e) {
            log.error("Error sending RECOGNITION-COMPLETE event: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送MRCP消息
     */
    private void sendMrcpMessage(ChannelHandlerContext ctx, MrcpMessage message) {
        try {
            log.debug("Preparing to send MRCP message: type={}, resource={}", 
                    message.getMessageType(), message.getResourceType());
            
            String messageStr = message.encode();
            log.debug("Encoded MRCP message length: {} characters", messageStr.length());
            log.debug("Encoded MRCP message: {}", messageStr);
            
            byte[] bytes = messageStr.getBytes(StandardCharsets.UTF_8);
            ByteBuf buffer = Unpooled.wrappedBuffer(bytes);
            ctx.writeAndFlush(buffer);
            
            log.debug("Successfully sent MRCP message ({} UTF-8 bytes)", bytes.length);
            
        } catch (Exception e) {
            log.error("Error sending MRCP message: {}", e.getMessage(), e);
            // 记录消息详情以便调试
            log.error("Message details: type={}, resource={}, headers={}", 
                    message.getMessageType(), message.getResourceType(), message.getAllHeaders());
        }
    }
    
    /**
     * 发送错误响应
     */
    private void sendErrorResponse(ChannelHandlerContext ctx, Exception error) {
        try {
            // 构建错误响应
            String errorMessage = String.format("MRCP Error: %s", error.getMessage());
            ByteBuf buffer = Unpooled.wrappedBuffer(errorMessage.getBytes(StandardCharsets.UTF_8));
            ctx.writeAndFlush(buffer);
            
            log.debug("Sent error response: {}", errorMessage);
            
        } catch (Exception e) {
            log.error("Error sending error response: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 发送进度响应（200 IN-PROGRESS）
     */
    private void sendProgressResponse(ChannelHandlerContext ctx, MrcpMessage request, int statusCode, String reasonPhrase) {
        try {
            MrcpResponse response = new MrcpResponse();
            response.setRequestId(request.getRequestId());
            response.setStatusCode(statusCode);
            response.setRequestState(reasonPhrase);
            response.setResourceType(request.getResourceType());
            
            // 添加必要的头部
            response.addHeader("Channel-Identifier", request.getHeader("Channel-Identifier"));
            response.addHeader("Completion-Cause", "000 success");
            
            sendMrcpMessage(ctx, response);
            log.info("Sent MRCP progress response {} {} for request ID: {}", 
                    statusCode, reasonPhrase, request.getRequestId());
            
        } catch (Exception e) {
            log.error("Error sending progress response: {}", e.getMessage(), e);
        }
    }
    
    /**
     * 获取存储的语法定义
     */
    public String getGrammar(String callId) {
        return grammarStorage.get(callId);
    }
    
    /**
     * 清理语法存储
     */
    public void clearGrammar(String callId) {
        grammarStorage.remove(callId);
        log.debug("Grammar cleared for Call-ID: {}", callId);
    }
    
    /**
     * 获取所有存储的语法信息
     */
    public void logGrammarStorage() {
        log.info("Grammar storage status: {} grammars stored", grammarStorage.size());
        grammarStorage.forEach((callId, grammar) -> {
            log.info("  Call-ID: {}, Grammar length: {} bytes", callId, grammar.length());
        });
    }
    
    @Override
    public void channelActive(ChannelHandlerContext ctx) {
        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        log.info("MRCP connection established from {}:{}", 
                remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort());
        
        // 添加连接建立后的调试信息
        log.info("MRCP channel is now active and ready to receive messages");
        log.info("Channel ID: {}, Remote Address: {}:{}", 
                ctx.channel().id(), 
                remoteAddress.getAddress().getHostAddress(), 
                remoteAddress.getPort());
    }
    
    @Override
    public void channelInactive(ChannelHandlerContext ctx) {
        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        log.info("MRCP connection closed from {}:{}", 
                remoteAddress.getAddress().getHostAddress(), remoteAddress.getPort());
        
        // 清理通道映射
        String callId = channelCallIdMap.remove(ctx);
        if (callId != null) {
            log.info("Cleaned up MRCP connection for Call-ID: {}", callId);
            
            // 注销MRCP回调
            try {
                mediaSessionManager.unregisterMrcpCallbacks(callId);
                log.info("Cleaned up MRCP callbacks for Call-ID: {} on channel disconnect", callId);
            } catch (Exception e) {
                log.error("Error cleaning up MRCP callbacks on channel disconnect: {}", e.getMessage(), e);
            }
            
            // 通知MediaSessionManager连接已关闭
            try {
                // 可以在这里添加连接关闭的处理逻辑
                log.debug("Notifying MediaSessionManager about connection closure for Call-ID: {}", callId);
            } catch (Exception e) {
                log.warn("Error notifying MediaSessionManager about connection closure: {}", e.getMessage());
            }
        } else {
            log.debug("No Call-ID mapping found for closed MRCP connection");
        }
        
        // 检查通道状态
        if (ctx.channel().isOpen()) {
            log.debug("MRCP channel is still open, closing it");
            ctx.close();
        }
    }
    
    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        InetSocketAddress remoteAddress = (InetSocketAddress) ctx.channel().remoteAddress();
        String remoteInfo = remoteAddress != null ? 
            remoteAddress.getAddress().getHostAddress() + ":" + remoteAddress.getPort() : "unknown";
        
        log.error("MRCP channel exception from {}: {}", remoteInfo, cause.getMessage(), cause);
        
        // 尝试发送错误响应
        try {
            sendErrorResponse(ctx, new Exception("Channel error: " + cause.getMessage()));
        } catch (Exception e) {
            log.warn("Failed to send error response: {}", e.getMessage());
        }
        
        // 检查通道状态并关闭
        if (ctx.channel().isOpen()) {
            log.info("Closing MRCP channel due to exception");
            ctx.close();
        }
    }
    
    /**
     * 生成NLSML格式的识别结果
     */
    private String generateNlsmlResult(RecognitionResult result, String sessionId) {
        if (result == null || result.getText() == null || result.getText().trim().isEmpty()) {
            return createEmptyNlsmlResult();
        }
        
        // 获取置信度分数，默认为0.5
        Double confidenceValue = result.getConfidence();
        double confidence = confidenceValue != null ? confidenceValue.doubleValue() : 0.5;
        // 获取存储的语法定义
        String grammarContent = getGrammar(sessionId);

        StringBuilder nlsml = new StringBuilder();
        nlsml.append("<?xml version=\"1.0\"?>\n");
        nlsml.append("<result>\n");

        if (grammarContent != null && !grammarContent.trim().isEmpty()) {
            // 解析语法定义并生成相应的NLSML
            String instance = generateInstanceFromGrammar(result.getText(), grammarContent);

            nlsml.append("  <interpretation confidence=\"").append(String.format("%.2f", confidence)).append("\">\n");
            nlsml.append("    <instance>").append(instance).append("</instance>\n");
            nlsml.append("    <input mode=\"speech\">").append(escapeXml(result.getText())).append("</input>\n");
            nlsml.append("  </interpretation>\n");
        } else {
            // 如果没有语法定义，使用简单格式
            nlsml.append("  <interpretation confidence=\"").append(String.format("%.2f", confidence)).append("\">\n");
            nlsml.append("    <instance>\n");
            nlsml.append("      <result>").append(escapeXml(result.getText())).append("</result>\n");
            nlsml.append("      <beginTime>").append(escapeXml(result.getBeginTime() + "")).append("</beginTime>\n");
            nlsml.append("      <duration>").append(escapeXml(result.getDuration() + "")).append("</duration>\n");
            nlsml.append("      <taskId>").append(escapeXml(result.getTaskId() + "")).append("</taskId>\n");
            nlsml.append("    </instance>\n");
            nlsml.append("    <input mode=\"speech\">").append(escapeXml(result.getText())).append("</input>\n");
            nlsml.append("  </interpretation>\n");
        }

        nlsml.append("</result>");
        return nlsml.toString();
        
    }
    

    
    /**
     * 根据语法定义生成实例数据
     * 解析SRGS语法并根据识别结果生成相应的语义结构
     */
    private String generateInstanceFromGrammar(String recognizedText, String grammarContent) {
        try {
            // 解析语法中的规则和标签
            if (grammarContent.contains("<tag>") && grammarContent.contains("</tag>")) {
                // 包含语义标签的语法
                return generateSemanticInstance(recognizedText, grammarContent);
            } else if (grammarContent.contains("<item>")) {
                // 简单的项目列表语法
                return generateSimpleInstance(recognizedText, grammarContent);
            } else {
                // 默认文本格式
                return "<text>" + escapeXml(recognizedText) + "</text>";
            }
        } catch (Exception e) {
            log.warn("Error parsing grammar for semantic interpretation: {}", e.getMessage());
            // 降级为简单文本格式
            return "<text>" + escapeXml(recognizedText) + "</text>";
        }
    }
    
    /**
     * 生成语义实例（包含tag的语法）
     */
    private String generateSemanticInstance(String recognizedText, String grammarContent) {
        StringBuilder instance = new StringBuilder();
        
        // 简单的语义解析 - 在实际应用中应该更复杂
        if (recognizedText.matches("\\d+")) {
            // 数字
            instance.append("<number>").append(recognizedText).append("</number>");
        } else if (recognizedText.toLowerCase().contains("是") || recognizedText.toLowerCase().contains("确认")) {
            // 确认命令
            instance.append("<confirm>true</confirm>");
            instance.append("<action>confirm</action>");
        } else if (recognizedText.toLowerCase().contains("否") || recognizedText.toLowerCase().contains("取消")) {
            // 取消命令
            instance.append("<confirm>false</confirm>");
            instance.append("<action>cancel</action>");
        } else {
            // 默认处理
            instance.append("<command>").append(escapeXml(recognizedText)).append("</command>");
        }
        
        return instance.toString();
    }
    
    /**
     * 生成简单实例（item列表语法）
     */
    private String generateSimpleInstance(String recognizedText, String grammarContent) {
        // 从语法中提取可能的选项
        return "<selected>" + escapeXml(recognizedText) + "</selected>";
    }
    
    /**
     * 创建空的NLSML结果（当没有识别到内容时）
     */
    private String createEmptyNlsmlResult() {
        StringBuilder nlsml = new StringBuilder();
        nlsml.append("<?xml version=\"1.0\"?>\n");
        nlsml.append("<result>\n");
        nlsml.append("  <noinput/>\n");
        nlsml.append("</result>");
        
        return nlsml.toString();
    }
    
    /**
     * XML转义
     */
    private String escapeXml(String text) {
        if (text == null) {
            return "";
        }
        return text.replace("&", "&amp;")
                  .replace("<", "&lt;")
                  .replace(">", "&gt;")
                  .replace("\"", "&quot;")
                  .replace("'", "&apos;");
    }
    
    /**
     * 获取真正的SIP Call-ID
     * 将MRCP层的Call-ID映射到SIP层的Call-ID
     */
    private String getSipCallId(MrcpMessage message, String mrcpCallId) {
        try {
            // 尝试通过Channel-Identifier查找SIP Call-ID
            String channelIdentifier = message.getHeader("Channel-Identifier");
            if (channelIdentifier != null && !channelIdentifier.trim().isEmpty()) {
                String sipCallId = mediaSessionManager.findCallIdByMrcpChannel(channelIdentifier);
                if (sipCallId != null) {
                    log.debug("Mapped MRCP Call-ID {} to SIP Call-ID: {}", mrcpCallId, sipCallId);
                    return sipCallId;
                }
            }
            
            // 如果没有找到映射，尝试直接使用MRCP Call-ID
            // 这可能适用于一些简单的情况
            if (mediaSessionManager.getMediaSession(mrcpCallId) != null) {
                log.debug("Using MRCP Call-ID directly as SIP Call-ID: {}", mrcpCallId);
                return mrcpCallId;
            }
            
            log.warn("No SIP Call-ID mapping found for MRCP Call-ID: {}", mrcpCallId);
            return null;
            
        } catch (Exception e) {
            log.error("Error mapping MRCP Call-ID to SIP Call-ID: {}", e.getMessage(), e);
            return null;
        }
    }
    
    /**
     * 注册MRCP消息回调
     * 创建一个回调函数，将MRCP消息发送到指定的通道上下文
     */
    private void registerMrcpCallback(String callId, ChannelHandlerContext ctx) {
        try {
            // 创建回调函数，用于将MRCP消息发送到这个通道
            MrcpMessageSender.MrcpMessageCallback callback = (message) -> {
                try {
                    sendMrcpMessage(ctx, message);
                } catch (Exception e) {
                    log.error("Error sending MRCP message via callback for Call-ID {}: {}", callId, e.getMessage(), e);
                }
            };
            
            // 向MediaSessionManager注册回调
            mediaSessionManager.registerMrcpChannelCallback(callId, callback);
            
            log.debug("Registered MRCP callback for Call-ID: {} with channel: {}", callId, ctx.channel().id());
            
        } catch (Exception e) {
            log.error("Failed to register MRCP callback for Call-ID: {}", callId, e);
        }
    }
    
}
